# @Author:黄景涛
# @Date: 2024/2/21
"""
请求参数的热加载处理、参数回填
"""

import re

from commons.hjt_tools import DebugTalk


class HotLoad:
    dtk = DebugTalk()

    def replace_get_value(self, data):
        """
        :param data:  base_url、url、Cookie、json、params等值
        :return: 热加载回填后的data
        """
        if not data or data is None:
            return data
        try:
            """1.保存原数据的类型"""
            original_type = type(data)

            str_data = str(data)
            """2.热加载替换"""
            str_data = self._hot_loading(str_data)

            """3.还原数据类型"""
            if original_type in (list, dict):
                import ast
                data = ast.literal_eval(str_data)
            else:
                data = original_type(str_data)
            return data
        except Exception as e:
            error_msg = f'{str(e)}\t ——— 热加载处理的数据：{data}'
            raise Exception(error_msg)

    @staticmethod
    def _hot_loading(str_data: str):
        """把str_data中，逐一执行每个热加载占位符中的函数，并用函数返回值替换"""

        # 基本匹配 ${func_name(*args)}
        pattern_str = r"\${(?P<func_name>.*?)\((?P<func_args>.*?)\)}"
        # 替换为非字符串 , 如："${len(abc)}"  -> 3
        pattern_other = r"([\"\'])\${(?P<func_name>.*?)\((?P<func_args>.*?)\)}\1"

        for hot_word in re.finditer(pattern_str, str_data):
            '''1.提取函数名称、函数的参数'''
            print(f'\n开始替换：')
            print(f'函数位置：{hot_word}')
            func_name = hot_word.group('func_name')
            func_args = hot_word.group('func_args')
            print(f'提取结果：{hot_word.groups()}')
            print(f'提取的函数名：{func_name}')

            '''2.处理参数'''
            try:
                func_args = eval(func_args)
                # 处理非元组，如：'abc'、[1,2,3]、{'a':1, 'b':2}
                if isinstance(func_args, (str, dict, list)):
                    func_args = (func_args,)
            except (SyntaxError, NameError):
                # 兼容处理：参数未加引号
                func_args = (func_args,)

            # 处理('',)
            if func_args[0] == '':
                func_args = tuple()
            print(f'提取的参数：{(arg for arg in func_args)}')

            '''3.处理函数对象'''
            try:
                # 从hjt_tools中执行自定义函数
                func_obj = getattr(HotLoad.dtk, func_name)
                print(f'自定义函数：{func_obj}')
            except AttributeError:
                try:
                    func_obj = __builtins__.get(func_name)
                    print(f'内置函数：{func_obj}')
                except AttributeError:
                    error_msg = f'不存在函数【{func_name}】'
                    raise Exception(error_msg)

            '''4.调用函数'''
            return_info = func_obj(*func_args)
            print(f'函数执行：{func_obj(*func_args)}')

            '''5.返回值的类型，回填'''
            if isinstance(return_info, str):
                str_data = re.sub(pattern_str, str(return_info), str_data, 1)
            else:
                str_data = re.sub(pattern_other, str(return_info), str_data, 1)
        print(f'替换结束！\n')
        return str_data


if __name__ == '__main__':
    getattr(__builtins__, 'len')
